'''
Created on 2013-4-10

@author: CL.Lam
'''
import sqlalchemy.types as types
from sys2do.model import DBSession
from sqlalchemy.schema import Sequence
from sqlalchemy.exc import ProgrammingError
import traceback


__all__ = ['ListFieldColumn', 'nextVal']


class ListFieldColumn( types.TypeDecorator ):
    impl = types.Text

    def process_bind_param( self, value, dialect ):
        if not value : return None
        if isinstance( value, basestring ) : return value
        if type( value ) == list : return "|".join( map( unicode, sorted( value ) ) )    # make sure the same value save the same
        return None

    def process_result_value( self, value, dialect ):
        if not value : return None
        return value.split( "|" )

    def compare_values( self, x, y ):    # x new value, y come from copy value]
        if x is None and y is None : return True
        if x is None or y is None : return False

        if isinstance( x, basestring ) : x = [x]
        if isinstance( y, basestring ) : x = [y]

        tmp_x = sorted( x )
        tmp_y = sorted( y )
        return tmp_x == tmp_y




def nextVal( seq ):
    try:
        s = Sequence( seq )
        s.create( DBSession.bind, checkfirst = True )    # if the seq is existed ,don't create again
        return DBSession.execute( s )
    except:
        traceback.print_exc()
        raise SystemError( 'Can not get the next value for sequence "%s"' % seq )


def genNo( seq, prefix, lth = 7 ):
    def _f():
        t = '%%s%%.%sd' % lth
        return t % ( prefix, nextVal( seq ) )
    return _f
